package com.sugon.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.dao.DeviceInfoDao;
import com.sugon.dao.SysDeptDao;
import com.sugon.entity.DeviceInfoEntity;
import com.sugon.entity.SysDeptEntity;
import com.sugon.modules.sys.consts.SysDeptConst;
import com.sugon.service.DeviceInfoService;
import com.sugon.service.SysDeptService;
import com.sugon.utils.ShiroUtils;
import com.sugon.utils.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service("sysDeptService")
public class SysDeptServiceImpl implements SysDeptService {

    @Resource
    private SysDeptDao sysDeptDao;
    @Resource
    private DeviceInfoDao deviceInfoDao;
    @Resource
    private DeviceInfoService deviceService;

    @Override
    public SysDeptEntity queryObject(String deptId) {
        return sysDeptDao.queryObject(deptId);
    }

    @Override
    public List<SysDeptEntity> queryList(Map<String, Object> map) {
        return sysDeptDao.queryList(map);
    }

    @Override
    public int save(SysDeptEntity sysDept) {
        String parentId = sysDept.getParentId();
        SysDeptEntity parent = sysDeptDao.queryByDeptId(parentId);
        Assert.notNull(parent, "父部门不存在！");
        // 查询当前父部门下下一节点
        sysDept.setId(RandomUtil.randomString(32));
        sysDept.setDeptId(generateSubDeptId(parentId, parent.getDeptLevel()));
        sysDept.setCreateTime(new Date());
        sysDept.setCreateUser(ShiroUtils.getUserId());
        sysDept.setStatus(0);
        sysDept.setDeptLevel(parent.getDeptLevel() + 1);
        return sysDeptDao.save(sysDept);
    }

    @Override
    public int update(SysDeptEntity sysDept) {
        sysDept.setUpdateTime(DateUtil.date());
        sysDept.setUpdateUser(ShiroUtils.getUserId());
        return sysDeptDao.update(sysDept);
    }

    /**
     * 级联更新
     * 当检测到所属组织结构发生变化时级联更新下面所有自部门的
     *
     * @param sysDept
     */
    @Override
    public void cascadeUpdate(SysDeptEntity sysDept) {
        String newParentId = sysDept.getParentId();
        SysDeptEntity newParent = sysDeptDao.queryByDeptId(newParentId);
        Assert.notNull(newParent, "父部门不存在！");
        /*
           判断更新部门信息时是否更新了上级部门
            如果需要更新上级部门，那么需要当前部门下不包含任何子部门
         */
        String oldDeptId = sysDept.getDeptId();
        SysDeptEntity existedDept = sysDeptDao.queryByDeptId(oldDeptId);
        Assert.notNull(existedDept, "当前部门不存在！");
        String oldParentId = existedDept.getParentId();
        if (StrUtil.isNotEmpty(oldParentId) && !oldParentId.equals(newParentId)) {
            /*
                生成自己新的dept_id、parent_id
                当父组织切换时，需要修改自身的deptLevel和deptId
             */
            sysDept.setDeptLevel(newParent.getDeptLevel() + 1);
            // 获取新的部门ID
            String newDeptId = generateSubDeptId(newParentId, newParent.getDeptLevel());
            sysDept.setDeptId(newDeptId);
            sysDept.setUpdateTime(DateUtil.date());
            sysDept.setUpdateUser(ShiroUtils.getUserId());
            int update = update(sysDept);
            if (update > 0) {
                // 更新子部门的
                List<SysDeptEntity> deptList = sysDeptDao.queryByParentId(oldDeptId);
                if (CollectionUtil.isNotEmpty(deptList)) {
                    for (SysDeptEntity dept : deptList) {
                        dept.setParentId(newDeptId);
                        cascadeUpdate(dept);
                    }
                }
                // 更新设备的
                List<DeviceInfoEntity> deviceList = deviceInfoDao.queryByDeptCode(oldDeptId);
                if (CollectionUtil.isNotEmpty(deviceList)) {
                    for (DeviceInfoEntity device : deviceList) {
                        device.setDeptCode(newDeptId);
                        deviceService.update(device);
                    }
                }
            }
        } else {
            update(sysDept);
        }

    }

    /**
     * 生成指定父组织下的子组织ID
     *
     * @param parentId  父组织ID
     * @param deptLevel 父组织level
     */
    private String generateSubDeptId(String parentId, Integer deptLevel) {
        // 生成新的部门ID
        String maxId = sysDeptDao.queryMaxIdByParentId(parentId, deptLevel + 1);
        return com.sugon.modules.utils.StrUtil.increase(maxId, parentId, 2, 1);
    }

    @Override
    public int delete(String deptId) {
        return sysDeptDao.delete(deptId);
    }

    @Override
    public List<String> queryDetpIdList(String parentId) {
        return sysDeptDao.queryDetpIdList(parentId);
    }

    @Override
    public String getSubDeptIdList(String deptId) {
        //部门及子部门ID列表
        List<String> deptIdList = new ArrayList<>();

        //获取子部门ID
        List<String> subIdList = queryDetpIdList(deptId);
        getDeptTreeList(subIdList, deptIdList);

        //添加本部门
        deptIdList.add(deptId);

        String deptFilter = StringUtils.join(deptIdList, ",");
        return deptFilter;
    }

    /**
     * 递归
     */
    public void getDeptTreeList(List<String> subIdList, List<String> deptIdList) {
        for (String deptId : subIdList) {
            List<String> list = queryDetpIdList(deptId);
            if (list.size() > 0) {
                getDeptTreeList(list, deptIdList);
            }

            deptIdList.add(deptId);
        }
    }

    //获取部门类别\
    @Override
    public List<String> getKey(String type) {
        return sysDeptDao.getDeptTypes(type);
    }

    @Override
    public List<SysDeptEntity> queryListByType(String deptType, Integer level) {
        Map<String, Object> map = new HashMap<>();
        map.put("deptType", deptType);
        if (level != null) {
            map.put("level", level);
        }
        return sysDeptDao.queryListByType(map);
    }

    @Override
    public List<SysDeptEntity> queryListByType2(String deptType) {
        Map<String, Object> map = new HashMap<>();

        map.put("deptType", deptType);
        List<SysDeptEntity> deptList = sysDeptDao.queryListByType2(map);
        return deptList;
    }

    @Override
    public List<SysDeptEntity> listPersonOrganTree(Map<String, Object> param) {
        //获取通用数据
        List<SysDeptEntity> pList = sysDeptDao.queryListByTY();
        List<SysDeptEntity> dList = sysDeptDao.queryListByRY(param);
        List<SysDeptEntity> list2 = new ArrayList<>();
        list2.addAll(pList);
        list2.addAll(dList);
        return list2;
    }

    @Override
    public List<SysDeptEntity> treeDeptBySCX() {
        /*
            部门数据分为通用和普通数据
            通用部分指的是：工厂、车间
            个性部分：会区分为设备和人员组织结构
         */
        List<SysDeptEntity> pList = sysDeptDao.queryListByTY();
        List<SysDeptEntity> dList = sysDeptDao.queryListBySB();
        List<SysDeptEntity> list2 = new ArrayList<>();
        list2.addAll(pList);
        list2.addAll(dList);
        return list2;
    }

    @Override
    public List<SysDeptEntity> treeDeptByLevel(Integer level) {
        //获取通用数据
        List<SysDeptEntity> pList = sysDeptDao.queryListByTY();
        List<SysDeptEntity> dList = sysDeptDao.queryListLTLevel(level);
        List<SysDeptEntity> list2 = new ArrayList<>();
        list2.addAll(pList);
        list2.addAll(dList);
        return list2;
    }

    @Override
    public String getDeptTypeById(String deptId) {
        return sysDeptDao.getDeptTypeById(deptId);
    }

    @Override
    public String getPEdept(String deptType) {
        return sysDeptDao.getPEdept(deptType);
    }

    @Override
    public List<SysDeptEntity> getZhuZCJ() {
        // 车间用户只可以看自己的车间
        String workshop = ShiroUtils.getWorkshop();
        if (StrUtil.isEmpty(workshop) || SysDeptConst.ZZGYC_CODE.equals(workshop)) {
            workshop = null;
        }
        return sysDeptDao.getZZCJ(workshop);
    }

    @Override
    public SysDeptEntity getByDCode(String dcode) {
        Map<String, Object> param = new HashMap<>();
        param.put("dcode", dcode);
        List<SysDeptEntity> depts = sysDeptDao.queryList(param);
        return CollectionUtil.isNotEmpty(depts) ? depts.get(0) : null;
    }

    @Override
    public List<SysDeptEntity> getByName(String dname) {
        Map<String, Object> param = new HashMap<>();
        param.put("dname", dname);
        return sysDeptDao.queryList(param);
    }

    @Override
    public List<SysDeptEntity> listDeviceOrganization(Integer deptLevel) {
        String whereSql = "";
        // 找出deptLevel=2且flag=2  或者 deptLevel=3 falg 0
        if (deptLevel <= 2) {
            whereSql = "FLAG = 2 AND DEPT_LEVEL <= " + deptLevel;
        } else {
            whereSql = "(FLAG = 2 AND DEPT_LEVEL <= 2) OR (FLAG = 0 AND DEPT_LEVEL > 2 AND DEPT_LEVEL <= " + deptLevel + ")";
        }
        return sysDeptDao.listDeviceOrganization(whereSql);
    }
}
